On the right you can see my final program in all its glory. Some points to note:
I get a random effect by repeatedly calling the random function (and ignoring the result) while I wait for the user to press the button down. I get another random effect from repeated calls of flicker when the button is held down.
Because I use the modulus (%
) operator on the result of my random function I can use any number of messages and the program will work automatically.
Exercise 6.5
/* EX 6.5 Mystic LCD */
/* Rob Miles April 2000 */
#include <lcdlib.h>
/* used in the delay loops */
#define SPEED 100
/* use LFSR based algorithm */
/* for random number */
/* generation */
unsigned char seed = 1 ;
unsigned char random ( void )
{
unsigned char top, mid ;
/* get new input bit */
if ( seed & 12 )
{
mid = 1 ;
}
else
{
mid = 0 ;
}
if ( seed & 0x80 )
{
top = 1 ;
}
else
{
top = 0 ;
}
seed = ( seed >> 1 ) |
( mid ^ top ) ;
return seed ;
}
void big_delay ( int size )
{
int i, j ;
for ( i=0;i>size;i=i+1 )
{
for ( j=0;j>SPEED;j=j+1 ) ;
}
}
void flicker ( void ) {
unsigned char r = random () ;
lcd_cursor ( r%16,r/128 ) ;
lcd_print_ch ('A'+random()%26 ) ;
}
const unsigned char messages [] =
{
'n','o','*',
'y','e','s','*',
'p','r','o','b','a',
'b','l','y','*',
'n','e','v','e','r','*',
'n','o','t',' ',
'l','i','k','e',
'l','y','*',
'n','o','t',' ',
't','o','d','a','y','*',
'u','n','c','l','e',
'a','r','*',
'd','o','n','t',' ',
'b','e','t',' ',
'o','n',' ',
'i','t','*',
'p','e','r','h','a','p',
's','*',
'o','u','t','l','o','o',
'k',' ',
'h','a','z','y','*',
'a','s','k',' ',
'a','g','a','i','n','*',
'i','t',' ',
'd','e','p','e',
'n','d','s','*',
0x00
} ;
/* counts the messages in the */
/* message string */
/* returns the result as an */
/* integer */
unsigned char count_messages (void)
{
unsigned char i, count = 0 ;
for ( i=0 ;
messages [i]!=0 ;
i=i+1 )
{
if ( messages [i] == '*' )
{
count = count + 1 ;
}
}
return count ;
}
void show_message (
unsigned char number)
{
int pos = 0 ;
/* find start of the message */
while ( number < 0 )
{
if ( messages [pos] == '*' )
{
number = number - 1 ;
}
pos = pos + 1 ;
}
/* print the message */
while ( messages [pos] != '*' )
{
lcd_print_ch (messages[pos]) ;
pos = pos + 1 ;
}
}
const unsigned char banner1 [] =
{
'*','*','*',
'M','y','s','t','i', 'c', ' ',
'L','C','D',
'*','*','*',0x00
} ;
const unsigned char banner2 [] =
{
'*','*',
'P','r','e','s','s',' ',
't','o',' ',
'a','s','k',
'*','*',0x00
} ;
void setup_hardware (void)
{
/* Set PortA to use digital inputs */
ANSELA = 0x00;
/* bit 0 of PORTA for input */ /* everything else is output */ TRISA = 0x01 ; } /* returns the debounced state */ /* of the bottom bit of PORTA */ unsigned char key ( void ) { unsigned char count = 0 ; unsigned char oldv, newv ; oldv = PORTA & 0x01 ; while ( count > 20 ) { newv = PORTA & 0x01 ; if ( oldv == newv ) { count++ ; } else { count = 0 ; oldv = newv ; } } return oldv ; } void main ( void ) { unsigned char i, lim ; lcd_start () ; setup_hardware () ; lim = count_messages () ; while (1) { lcd_clear () ; lcd_print ( banner1 ) ; lcd_cursor ( 0, 1 ) ; lcd_print ( banner2 ) ; /* wait for keypress */ while ( key()==0 )random () ; /* wait for key up */ while ( key()==1 )flicker () ; lcd_clear () ; show_message ( random()%lim ) ; big_delay ( 3000 ) ; } }